package net.kleinhenz.droidshop.system;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Map.Entry;
import java.util.jar.Manifest;

import javax.servlet.ServletContext;

import org.apache.log4j.Level;

public class ApplicationConfiguration 
{
    public static final String KEY_DEBUGMODE = "net.kleinhenz.droidshop.debugmode";
    public static final String KEY_PERSISTENCEUNIT = "net.kleinhenz.droidshop.persistenceunit";
    public static final String KEY_AMAZON_ACCESSKEY = "net.kleinhenz.droidshop.amazon.accesskey";
    public static final String KEY_AMAZON_ASSOCIATEID = "net.kleinhenz.droidshop.amazon.associateid";
    public static final String KEY_AMAZON_MAX_PRICE_PAGES = "net.kleinhenz.droidshop.amazon.maxpricepages";
    public static final String KEY_AMAZON_MAX_REVIEW_PAGES = "net.kleinhenz.droidshop.amazon.maxreviewpages";
    
    private static int intBuffer = -1;
    private static String stringBuffer = null;
    
    private static Properties configuration = null;

    static 
    {
        if (!inJ2EEMode()) 
        {
            Logger.getLogger().log(Level.INFO, "Not running in J2EE mode. Using classpath properties in configuration.properties as configuration source.");
            configuration = new Properties();
            try 
            {
                configuration.load("".getClass().getResourceAsStream("/configuration.properties"));
            } 
            catch (IOException e) 
            {
                Logger.getLogger().log(Level.FATAL, "Error loading default configuration properties.", e);
                throw new RuntimeException("Error loading default configuration properties.", e);
            } 
            catch (NullPointerException e) 
            {
                Logger.getLogger().log(Level.FATAL, "Error loading default configuration properties.", e);
                throw new RuntimeException("Error loading default configuration properties.", e);
            }
        } 
        else
            Logger.getLogger().log(Level.INFO,
                "Running in J2EE mode. Using servlet context parameters as configuration source.");
    }

    public static String getConfiguration(String key) 
    {
        if (!inJ2EEMode())
            // we're running in non-J2EE mode
            return configuration.getProperty(key);
        else
        {
            // we're running in J2EE mode
            return WSServletContextListener.getServletContext().getInitParameter(key);            
        }
    }

    public static boolean inDebugMode() 
    {
        if (getConfiguration(KEY_DEBUGMODE) != null && getConfiguration(KEY_DEBUGMODE).equals("true"))
            return true;
        else
            return false;
    }

    private static boolean inJ2EEMode() 
    {
        return WSServletContextListener.inJ2EEMode();
    }

    public static String getVersion() 
    {
        return getManifestInfo("Implementation-Version") + " - " + getManifestInfo("Implementation-Build");
    }

    public static int getIntBuffer() 
    {
        return intBuffer;
    }

    public static void setIntBuffer(int intBuffer) 
    {
        ApplicationConfiguration.intBuffer = intBuffer;
    }

    public static String getStringBuffer() 
    {
        return stringBuffer;
    }

    public static void setStringBuffer(String stringBuffer) 
    {
        ApplicationConfiguration.stringBuffer = stringBuffer;
    }

    private static String getManifestInfo(String key) 
    {
        try 
        {
            ServletContext ctx = WSServletContextListener.getServletContext();

            if (ctx == null)
                return "n/a";

            InputStream manifestStream = ctx.getResourceAsStream("META-INF/MANIFEST.MF");
            Manifest manifest = new Manifest(manifestStream);
            Iterator< Entry< Object , Object >> entries = manifest.getMainAttributes().entrySet().iterator();
            while (entries.hasNext()) 
            {
                Map.Entry< Object , Object > entry = entries.next();
                String mKey = entry.getKey().toString();
                if (key.equals(mKey))
                    return (String) entry.getValue();
            }

            return null;
        } 
        catch (IOException e) 
        {
            return "n/a";
        }
    }
}
